<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>this 对象</title>
</head>

<body>
    <script>
        (function () {
            // 在闭包中使用this对象也可能会导致一些问题
            // this对象 是运行时基于函数的执行环境绑定的
            // 在全局函数中，this===window
            // 而当函数被作为某个对象的方法调用时this等于那个对象
            // 在通过call(),apply()，bind()改变函数执行环境的情况下，this就会指向传入这个方法第一个参数上

            // 不过匿名函数的执行环境具有全局性，因此其this对象通常指向window
            // 但有时候由于编写闭包的方式不同，这一点可能不会那么明显

            var name="The Window";

            var obj={
                name:"My obj",
                getName:function(){
                    return function(){
                        return this.name;
                    };
                }
            }

            // 因为每一个函数在被调用时都会自动取得两个特殊的变量：arguments、this
            // 因此 obj.getName()调用时取得了这两个变量，this指向object
            // 但同时obj.getName()() 内部匿名函数调用时也会取得arguments、this，
            // 因此这里的this 覆盖了 obj.getName() 里的this,
            // 而在作用域链上搜索这个变量时，会优先搜索本地的活动对象，因此永远也不可能直接访问到外部函数的this和arguments
            // 而此时obj.getName()() 的this指向全局执行环境 因此指向window 所以输出了 “This Window”;

            var result=obj.getName()();
            console.log(result);//This Window

            // 但我们可以利用闭包中内部函数引用外部函数变量对象的方法，将外部this或arguments 新建变量保存下来
            // 在内部保持对它的引用，这样就可以正常访问外部的this的指向了，
            // 虽然内部函数也会产生this，但我们已经不需要它了
 
            var obj2={
                name:"My obj2",
                getName:function(){
                    var that=this;
                    return function(){
                        return that.name;
                    };
                }
            }

            var result2=obj2.getName()();
            console.log(result2);//My obj2
        })();
    </script>
</body>

</html>